package com.lt.flashcard.view;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.GlobalCommand;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.image.AImage;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.select.Selectors;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Div;
import org.zkoss.zul.Image;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

import com.lt.flashcard.Utility;
import com.lt.flashcard.model.entity.Flashcard;
import com.lt.flashcard.model.entity.FlashcardSet;

public class flashcardModalUploadImage {
	private org.zkoss.image.AImage img;
	private FlashcardSet flashcardSet;
	@Wire("#modalDialog")
	private Window win;
	@Wire
	Div pic;
	@Wire
	Textbox tx1;
	@Wire
	Textbox ty1;
	@Wire
	Textbox tw;
	@Wire
	Textbox th;
	@Wire
	Image image;
	@Wire
	Image realtime_img;
	private String wri;
	private String hri;
	private int w;
	private int h;
	private Component comp;
	
	public Component getComp() {
    	return comp;
    }
	public void setComp(Component comp) {
    	this.comp = comp;
    }
	public int getW() {
		return w;
	}
	public void setW(int w) {
		this.w = w;
	}
	public int getH() {
		return h;
	}
	public void setH(int h) {
		this.h = h;
	}
	private Flashcard flashcard;
	private String type;
	
	
	public void setImg(org.zkoss.image.AImage img){
	    this.img = img;
	}
	public org.zkoss.image.AImage getImg(){
	    return img;
	}
	public void setWri(String wri) {
		this.wri = wri;
	}
	public String getWri() {
		return this.wri;
	}
	public void setHri(String hri) {
		this.hri = hri;
	}
	public String getHri() {
		return this.hri;
	}
	@Init
    public void init(@ContextParam(ContextType.VIEW) Component view,
            @ExecutionArgParam("fOrFs") Object object,
            @ExecutionArgParam("key") Object types,
            @ExecutionArgParam("img") Object oImg,
            @ExecutionArgParam("w") Object w,
            @ExecutionArgParam("h") Object h) {
        this.type = (String) types;
        this.w = (Integer) w;
    	this.h = (Integer) h;
    	
        if(type.equals("fs")){
        	this.flashcardSet = (FlashcardSet) object;
        	this.img = (AImage) oImg;        	
        	wri = "125";
        	hri = "125";
        }else{
        	this.flashcard = (Flashcard) object;
        	this.img = (AImage) oImg;
        	wri = "230";
        	hri = "135";
        }
    }
	
	@AfterCompose
    public void afterCompose(@ContextParam(ContextType.VIEW) Component view) throws IOException{
		Selectors.wireComponents(view, this, false);
        displayImage();
    }
	
	public void displayImage() throws IOException{
		BufferedImage resizedImage = scaledImage();
		image.setContent(resizedImage);
        realtime_img.setContent(resizedImage);
        if(type.equals("fs")){
            Clients.evalJavaScript("$('.image').imgAreaSelect({remove:true});");
            Clients.evalJavaScript("setTimeout(\"$('.image').imgAreaSelect({aspectRatio: '1:1', x1: 0, y1: 0, x2: 125, y2: 125, minHeight:125, minWidth:125, onSelectChange: preview, handles: true})\",500)");
        }else{
        	Clients.evalJavaScript("$('.image').imgAreaSelect({remove:true});");
            Clients.evalJavaScript("setTimeout(\"$('.image').imgAreaSelect({aspectRatio: '230:135',  x1: 0, y1: 0, x2: 230, y2: 135, minHeight:135, minWidth:135 ,onSelectChange: preview, handles: true})\",500)");
        }
        Clients.evalJavaScript("$('.realtime_img').css({width:Math.round("+ w +")+'px', marginLeft: Math.round(0), marginTop: Math.round(0)});");
        img = new AImage("", image.getContent().getStreamData());
	}
	@NotifyChange("img")
	public BufferedImage scaledImage() throws IOException{
        java.awt.image.BufferedImage originalImage = ImageIO.read(img.getStreamData());	
        BufferedImage resizedImage = new BufferedImage(w, h, BufferedImage.SCALE_SMOOTH);
		Graphics2D g = resizedImage.createGraphics();
		g.drawImage(originalImage, 0, 0, w, h, null);
		g.dispose();
		return resizedImage;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Command("saveAndClose")
    public void save() throws IOException {
		int x1 = 0;
		int y1 = 0;
		int w = new Integer(wri);
		int h = new Integer(hri);
		if(tx1.getValue() != null && tx1.getValue() != ""){
			//crop image
			x1 = new Integer(tx1.getValue());
			y1 = new Integer(ty1.getValue());
			w = new Integer(tw.getValue());
			h = new Integer(th.getValue());
		}
		java.awt.image.BufferedImage resizedImage = ImageIO.read(img
			    .getStreamData());
		BufferedImage cropImage = resizedImage.getSubimage(x1, y1, w, h);
		realtime_img.setContent(cropImage);
		
		//save image
		String img = Utility.saveImage(realtime_img.getContent().getStreamData());
		if(type.equals("fs") || type.equals("f")){
			if(type.equals("fs")) {
				//TODO delete old image
				this.flashcardSet.setImage(img);
				Map arg = new HashMap();
				arg.put("flashcardset", this.flashcardSet);
				BindUtils.postGlobalCommand("fCoS", null, "refreshvaluesSet", arg);
	        } else {
	        	//TODO delete old image
	        	Clients.evalJavaScript("$('.tdimage').show();"
						+ "$('.fdefinition').css({width: '210px', 'margin-left': '0px'});");
	        	this.flashcard.setImage(img);
	        	Map arg = new HashMap();
				arg.put("flashcard", this.flashcard);
				BindUtils.postGlobalCommand("fCoS", null, "refreshvaluesFC", arg);
	        }
        } 
		
		//close modal
        win.detach();
	    
    }
	@Command("close")
	public void close(){
		win.detach();
	}
	
	@GlobalCommand
	@NotifyChange({ "flashcardSet" })
	public void refreshvaluesSet(@BindingParam("flashcardset") FlashcardSet flashcardset) {
		this.flashcardSet = flashcardset;
	}
	
	@GlobalCommand
	@NotifyChange({ "flashcard" })
	public void refreshvaluesFC(@BindingParam("flashcard") Flashcard flashcard) throws IOException {
		this.flashcard = flashcard;
	}
}
